
#include "stdafx.h"
#include "Shape.h"

CShape::CShape()
{
	m_type = typeA;
	m_direction = dirNorth;
	SetType(typeA);
}

CShape::CShape(int type, int dir)
{
	SetType(type);
	SetDirection(dir);
}

int CShape::GetType()
{
	return m_type;
}

void CShape::SetType(int type)
{
	const static BYTE shapes[TYPE_COUNT][SHAPE_WIDTH][SHAPE_WIDTH] = {
		// typeA
		{
			{ 0, 0, 0, 0 },
			{ 0, 0, 0, 0 },
			{ 1, 1, 1, 1 },
			{ 0, 0, 0, 0 },
		},

		// typeB
		{
			{ 0, 0, 0, 0 },
			{ 0, 1, 1, 0 },
			{ 1, 1, 0, 0 },
			{ 0, 0, 0, 0 },
		},

		// typeC
		{
			{ 0, 0, 0, 0 },
			{ 1, 1, 0, 0 },
			{ 0, 1, 1, 0 },
			{ 0, 0, 0, 0 },
		},

		// typeD
		{
			{ 0, 1, 0, 0 },
			{ 1, 1, 1, 0 },
			{ 0, 0, 0, 0 },
			{ 0, 0, 0, 0 },
		},

		// typeE
		{
			{ 0, 0, 0, 0 },
			{ 0, 1, 1, 0 },
			{ 0, 1, 1, 0 },
			{ 0, 0, 0, 0 },
		},
		// typeF
		{
			{ 0, 0, 0, 0 },
			{ 0, 1, 1, 0 },
			{ 0, 0, 1, 0 },
			{ 0, 0, 1, 0 },
		},

		// typeG
		{
			{ 0, 0, 0, 0 },
			{ 0, 1, 1, 0 },
			{ 0, 1, 0, 0 },
			{ 0, 1, 0, 0 },
		}
	};
	const static Color colors[TYPE_COUNT] = {
		Color::Red, Color::YellowGreen, Color::Green, Color::Blue, Color::Magenta, Color::DarkCyan, Color::Gray
	};

	if (type >= typeA && type <= typeG) {
		memcpy(m_buffer, shapes[type], sizeof(m_buffer));
		m_type = type;
		m_color = colors[m_type];
	}
}

void CShape::Rotate(bool bLeft)
{
	int N = SHAPE_WIDTH;
	int i, j;
	BYTE buffer[SHAPE_WIDTH][SHAPE_WIDTH];

	switch (m_type) {
	case typeB:
	case typeC:
	case typeD:
		N = N - 1;
		break;

	default:
		break;
	}

	memset(buffer, 0, sizeof(buffer));
    if (bLeft) {
        for (j = N-1; j >= 0; j--) {
            for (i = 0; i < N; i++) {
                buffer[N-j-1][i] = m_buffer[i][j];
            }
        }

		if (--m_direction < dirNorth) {
			m_direction = dirWest;
		}
    }
    else {
        for (i = 0; i < N; i++) {
            for (j = 0; j < N; j++) {
                buffer[j][N-i-1] = m_buffer[i][j];
            }
        }

		if (++m_direction > dirWest) {
			m_direction = dirNorth;
		}
    }

	memcpy(m_buffer, buffer, sizeof(m_buffer));
}

int CShape::GetDirection()
{
	return m_direction;
}

void CShape::SetDirection(int dir)
{
	if (dir >= dirNorth && dir <= dirWest) {
		int diff = dir - m_direction;

		for (int i = 0; i < abs(diff); i++) {
			Rotate(diff < 0);
		}
	}
}

Color CShape::GetColor()
{
	return m_color;
}

void CShape::SetColor(Color color)
{
	m_color = color;
}

bool CShape::IsRowBlank(int row)
{
	if (row >= 0 && row < SHAPE_WIDTH) {
		for (int i = 0; i < SHAPE_WIDTH; i++) {
			if (m_buffer[row][i]) {
				return false;
			}
		}
		return true;
	}

	return false;
}

bool CShape::IsColBlank(int col)
{
	if (col >= 0 && col < SHAPE_WIDTH) {
		for (int i = 0; i < SHAPE_WIDTH; i++) {
			if (m_buffer[i][col]) {
				return false;
			}
		}
		return true;
	}

	return false;
}

